{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "120f52c4",
   "metadata": {},
   "source": [
    "--------\n",
    "* 记录人：曾巧仪\n",
    "* 时间：2021-11-29\n",
    "* week14\n",
    "* 主要参考文档：\n",
    ">1.[python官方文档](https://python.org/doc)  \n",
    ">2.[博客--函数](https://www.cnblogs.com/xuzhichao/p/11570285.html)\n",
    "--------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5675d9be",
   "metadata": {},
   "source": [
    "# 本周内容\n",
    ">1、函数的定义  \n",
    ">2、如何使用函数  \n",
    ">3、函数的返回值  \n",
    ">4、使用注释改进文档  \n",
    ">5、传递任意数量的实参  \n",
    ">6、函数与模块  "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a7f98c5b",
   "metadata": {},
   "source": [
    "## 1.函数的定义\n",
    "---\n",
    "\n",
    "```\n",
    "def:定义函数的关键字\n",
    "fib：函数名\n",
    "(n)：定义函数的参数\n",
    "\"\"\"\"\"\"：文档描述\n",
    "代码块：\n",
    "     a, b = 0, 1\n",
    "     while a < n:\n",
    "        print(a, end=' ')\n",
    "         a, b = b, a+b\n",
    "     print()\n",
    "```\n",
    "---\n",
    "* 定义函数：\n",
    "\n",
    "> 1.def 定义函数的第一步  \n",
    "> 2.def function_name  \n",
    ">> a.function_name 遵循变量名称定义的规则  \n",
    "\n",
    "> 3.函数名称后加上\"():\":def function_name(): ===> f(x)=2x  \n",
    "\n",
    "* 书写函数体\n",
    "> 1.函数的注释  \n",
    "> 2.写函数的具体操作（函数体）  \n",
    "> 3.注意：函数也是需要有tab键的间距\n",
    "\n",
    "* 使用函数（函数的调用）\n",
    "> 1.function_name()\n",
    "\n",
    "* 函数存在的意义"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "621d7ba4",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):    # write Fibonacci series up to n\n",
    "    \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "    a, b = 0, 1\n",
    "    while a < n:\n",
    "        print(a, end=' ')\n",
    "        a, b = b, a+b\n",
    "    print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "8445e918",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 \n"
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a32119a1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function fib in module __main__:\n",
      "\n",
      "fib(n)\n",
      "    Print a Fibonacci series up to n.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(fib)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "bc883cbf",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 尝试：写一个实现hello world的函数\n",
    "def hello():\n",
    "    \"\"\"打印hello world\"\"\"\n",
    "    print(\"hello world!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "8d2324e8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world!\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "292216f4",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 思考函数存在的意义？\n",
    "# 1.可以通过调用函数的方式实现某个功能，使用人不需要考虑函数代码内容  \n",
    "# 2.节省时间，提升应用的效率  \n",
    "# 3.函数一旦定义，就可按照一定的规则重复使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a6cabefd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义了一个名字叫“search4vowels” 函数\n",
    "def search4vowels(word):\n",
    "    \"\"\"\n",
    "    打印文本中出现的元音字母\n",
    "    请输入你想要查询的文本内容\n",
    "    \"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    found = vowels.intersection(set(word)) # 交集运算\n",
    "    print(found)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "3bbb0742",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function search4vowels in module __main__:\n",
      "\n",
      "search4vowels(word)\n",
      "    打印文本中出现的元音字母\n",
      "    请输入你想要查询的文本内容\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(search4vowels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "429f02f8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"bgfhje\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "b5d9f676",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e', 'a'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"fbnjdsadekw\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8f36e531",
   "metadata": {},
   "source": [
    "* 下面的方法是不是太重复了，主要原因是没有对重复功能的代码块有特殊的定义（如：名称，注释等）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "34e87c38",
   "metadata": {},
   "outputs": [],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e1eb2b71",
   "metadata": {},
   "outputs": [],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77515fc2",
   "metadata": {},
   "source": [
    "## 3.函数的参数\n",
    "\n",
    "* <font style=\"color:red\">注意：函数的参数可以没有，如果有参数，则如下（分为形式参数和实际参数）:</font>\n",
    "\n",
    "> 1.形式参数（形参）  \n",
    ">> 1.在定义过程中，函数的参数为形式参数  \n",
    "\n",
    "> 2.实际参数（实参）  \n",
    ">> 1.调用函数过程中，函数的参数为实际参数  \n",
    ">> 2.调用函数时，形式参数被分配空间，成为实际参数并应用起来  \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "2c385263",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'hello' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-1-59c290633c6a>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# 函数式可以没有参数的\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mhello\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'hello' is not defined"
     ]
    }
   ],
   "source": [
    "# 函数式可以没有参数的\n",
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "166bfc75",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义参数\n",
    "def greet_user(username):\n",
    "    \"\"\"显示简单的问候语，输入你的名字\"\"\"\n",
    "    print(\"hello,\" + username.title()+\"!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "de4cbee8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Zengqiaoyi!\n"
     ]
    }
   ],
   "source": [
    "# 调用参数： username = \"zengqiaoyi\"\n",
    "greet_user(\"zengqiaoyi\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "167ef0d7",
   "metadata": {},
   "source": [
    "* 当参数不止一个时：\n",
    "\n",
    "> 1.位置参数(positional argument)  \n",
    ">> A.形式参数有多个值，如果实际参数直接赋值，要按照形式参数的先后顺序，这种方式称：位置参数赋值  \n",
    ">> B.在调用函数过程中需要考虑如下：  \n",
    ">>> a.考虑位置  \n",
    ">>> b.考虑个数    \n",
    "\n",
    "> 2.[关键字参数](https://docs.python.org/3/tutorial/controlflow.html#keyword-arguments)   \n",
    ">> A.在调用函数时使用，我们直接在实参中 用赋值的方式去定义形参  \n",
    ">> B.不需要考虑顺序，因为赋值已经确定了形式参数的值  \n",
    "\n",
    "> 3.[默认参数](https://docs.python.org/3/tutorial/controlflow.html#default-argument-values)  \n",
    ">> A.默认参数写在 形式参数中（预计有大量的调用会使用到的值，可以预先设置）  \n",
    ">> B.默认参数存在的话，实际调用过程中可以省略赋值的过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "dbf9a278",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 请注意，有两个参数\n",
    "def describe_pet(animal_type,pet_name):\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \" + pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "d492d95b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "My dog's name is 秋秋.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"秋秋\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "026270fd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have acat.\n",
      "My cat's name is 冬冬.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"cat\",\"冬冬\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "120188fd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "My dog's name is 秋秋.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数\n",
    "describe_pet(animal_type=\"dog\",pet_name=\"秋秋\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "bcfde8f1",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() got an unexpected keyword argument 'animal_name'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-17-364d11428585>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdescribe_pet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0manimal_name\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"秋秋\"\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpet_type\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m\"dog\"\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: describe_pet() got an unexpected keyword argument 'animal_name'"
     ]
    }
   ],
   "source": [
    "describe_pet(animal_name=\"秋秋\",pet_type=\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "87dc78c0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 默认参数（写在形式参数中的）\n",
    "\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "    \"\"\"显示宠物信息,animal_type 的默认值'dog'\"\"\"\n",
    "    print(\"\\nI have a\" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \" + pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9a8410ad",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "My dog's name is 秋秋.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"秋秋\",\"dog\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c2ec1ee5",
   "metadata": {},
   "source": [
    "--------\n",
    "* 实操和注意（参数部分）\n",
    "\n",
    "> 1.如果想 关键字参数 和 位置参数共同使用\n",
    ">> A.positional argument follows keyword argument(位置参数需要放在关键字参数的前面）  \n",
    ">> B.关键字参数放在末尾（均事关键字，不考虑顺序）  \n",
    "\n",
    "> 2.默认参数  \n",
    ">> A.non-default argument follows default argument(非默认参数需要放在默认参数的前面)  \n",
    ">> B.默认参数放在末尾（均是默认参数，不考虑顺序）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "e01916e3",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "positional argument follows keyword argument (<ipython-input-18-d219ba831f78>, line 6)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-18-d219ba831f78>\"\u001b[1;36m, line \u001b[1;32m6\u001b[0m\n\u001b[1;33m    func_test(x=1,2)      #？\u001b[0m\n\u001b[1;37m                  ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m positional argument follows keyword argument\n"
     ]
    }
   ],
   "source": [
    "#eg1\n",
    "def func_test(x,y):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    \n",
    "func_test(x=1,2)      #？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "0ae99170",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n"
     ]
    }
   ],
   "source": [
    "#eg2\n",
    "def func_test(x,y):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    \n",
    "func_test(1,y=2)      #？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "9c539eaa",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg2\n",
    "def func_test(x,y,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,z=3)      #？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "f96a0463",
   "metadata": {},
   "outputs": [
    {
     "ename": "SyntaxError",
     "evalue": "non-default argument follows default argument (<ipython-input-29-5f5c8c259261>, line 2)",
     "output_type": "error",
     "traceback": [
      "\u001b[1;36m  File \u001b[1;32m\"<ipython-input-29-5f5c8c259261>\"\u001b[1;36m, line \u001b[1;32m2\u001b[0m\n\u001b[1;33m    def func_test(x,y=4,z):\u001b[0m\n\u001b[1;37m                  ^\u001b[0m\n\u001b[1;31mSyntaxError\u001b[0m\u001b[1;31m:\u001b[0m non-default argument follows default argument\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,y=4,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,3)      #？"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "f30e9bda",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,z,y=3):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,3,5)    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ed257eb2",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
